package com.autoglm.android.core.execution

import android.accessibilityservice.AccessibilityService
import android.accessibilityservice.GestureDescription
import android.content.Context
import android.content.Intent
import android.graphics.Path
import android.os.Build
import android.os.Bundle
import androidx.annotation.RequiresApi
import com.autoglm.android.core.accessibility.ElementCriteria
import com.autoglm.android.core.accessibility.ScreenAnalyzer
import com.autoglm.android.core.accessibility.UIElement
import com.autoglm.android.core.models.StepResult
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.withContext
import kotlin.coroutines.resume
import kotlin.coroutines.suspendCoroutine

/**
 * 动作执行器接口，负责执行界面操作
 */
interface ActionExecutor {
    /**
     * 点击屏幕上的坐标
     * @param x X坐标
     * @param y Y坐标
     * @return 操作结果
     */
    suspend fun click(x: Int, y: Int): StepResult
    
    /**
     * 长按屏幕上的坐标
     * @param x X坐标
     * @param y Y坐标
     * @param durationMs 长按时间(毫秒)
     * @return 操作结果
     */
    suspend fun longClick(x: Int, y: Int, durationMs: Long = 1000): StepResult
    
    /**
     * 滑动操作
     * @param fromX 起始X坐标
     * @param fromY 起始Y坐标
     * @param toX 目标X坐标
     * @param toY 目标Y坐标
     * @param durationMs 滑动时间(毫秒)
     * @return 操作结果
     */
    suspend fun swipe(fromX: Int, fromY: Int, toX: Int, toY: Int, durationMs: Long = 500): StepResult
    
    /**
     * 点击UI元素
     * @param element 目标UI元素
     * @return 操作结果
     */
    suspend fun clickElement(element: UIElement): StepResult
    
    /**
     * 根据条件查找并点击元素
     * @param criteria 查找条件
     * @return 操作结果
     */
    suspend fun findAndClickElement(criteria: ElementCriteria): StepResult
    
    /**
     * 输入文本
     * @param text 要输入的文本
     * @return 操作结果
     */
    suspend fun inputText(text: String): StepResult
    
    /**
     * 按下返回键
     * @return 操作结果
     */
    suspend fun backPress(): StepResult
    
    /**
     * 按下主页键
     * @return 操作结果
     */
    suspend fun homePress(): StepResult
    
    /**
     * 启动应用
     * @param packageName 应用包名
     * @return 操作结果
     */
    suspend fun launchApp(packageName: String): StepResult
}

/**
 * 基于AccessibilityService的动作执行器实现
 */
@RequiresApi(Build.VERSION_CODES.N)
class AccessibilityActionExecutor(
    private val context: Context,
    private val accessibilityService: AccessibilityService,
    private val screenAnalyzer: ScreenAnalyzer
) : ActionExecutor {
    
    override suspend fun click(x: Int, y: Int): StepResult = withContext(Dispatchers.IO) {
        try {
            val path = Path().apply {
                moveTo(x.toFloat(), y.toFloat())
            }
            
            val gestureBuilder = GestureDescription.Builder()
            val gesture = GestureDescription.StrokeDescription(path, 0, 10)
            gestureBuilder.addStroke(gesture)
            
            val result = suspendCoroutine<Boolean> { continuation ->
                accessibilityService.dispatchGesture(
                    gestureBuilder.build(),
                    object : AccessibilityService.GestureResultCallback() {
                        override fun onCompleted(gestureDescription: GestureDescription) {
                            continuation.resume(true)
                        }
                        
                        override fun onCancelled(gestureDescription: GestureDescription) {
                            continuation.resume(false)
                        }
                    },
                    null
                )
            }
            
            return@withContext if (result) {
                StepResult.success()
            } else {
                StepResult.failure("点击操作被取消")
            }
        } catch (e: Exception) {
            return@withContext StepResult.failure("点击操作失败: ${e.message}")
        }
    }
    
    override suspend fun longClick(x: Int, y: Int, durationMs: Long): StepResult = withContext(Dispatchers.IO) {
        try {
            val path = Path().apply {
                moveTo(x.toFloat(), y.toFloat())
            }
            
            val gestureBuilder = GestureDescription.Builder()
            val gesture = GestureDescription.StrokeDescription(path, 0, durationMs)
            gestureBuilder.addStroke(gesture)
            
            val result = suspendCoroutine<Boolean> { continuation ->
                accessibilityService.dispatchGesture(
                    gestureBuilder.build(),
                    object : AccessibilityService.GestureResultCallback() {
                        override fun onCompleted(gestureDescription: GestureDescription) {
                            continuation.resume(true)
                        }
                        
                        override fun onCancelled(gestureDescription: GestureDescription) {
                            continuation.resume(false)
                        }
                    },
                    null
                )
            }
            
            return@withContext if (result) {
                StepResult.success()
            } else {
                StepResult.failure("长按操作被取消")
            }
        } catch (e: Exception) {
            return@withContext StepResult.failure("长按操作失败: ${e.message}")
        }
    }
    
    override suspend fun swipe(fromX: Int, fromY: Int, toX: Int, toY: Int, durationMs: Long): StepResult = withContext(Dispatchers.IO) {
        try {
            val path = Path().apply {
                moveTo(fromX.toFloat(), fromY.toFloat())
                lineTo(toX.toFloat(), toY.toFloat())
            }
            
            val gestureBuilder = GestureDescription.Builder()
            val gesture = GestureDescription.StrokeDescription(path, 0, durationMs)
            gestureBuilder.addStroke(gesture)
            
            val result = suspendCoroutine<Boolean> { continuation ->
                accessibilityService.dispatchGesture(
                    gestureBuilder.build(),
                    object : AccessibilityService.GestureResultCallback() {
                        override fun onCompleted(gestureDescription: GestureDescription) {
                            continuation.resume(true)
                        }
                        
                        override fun onCancelled(gestureDescription: GestureDescription) {
                            continuation.resume(false)
                        }
                    },
                    null
                )
            }
            
            return@withContext if (result) {
                StepResult.success()
            } else {
                StepResult.failure("滑动操作被取消")
            }
        } catch (e: Exception) {
            return@withContext StepResult.failure("滑动操作失败: ${e.message}")
        }
    }
    
    override suspend fun clickElement(element: UIElement): StepResult {
        return click(element.bounds.centerX, element.bounds.centerY)
    }
    
    override suspend fun findAndClickElement(criteria: ElementCriteria): StepResult = withContext(Dispatchers.IO) {
        try {
            val element = screenAnalyzer.findElement(criteria)
                ?: return@withContext StepResult.failure("找不到匹配的元素")
                
            return@withContext clickElement(element)
        } catch (e: Exception) {
            return@withContext StepResult.failure("查找并点击元素失败: ${e.message}")
        }
    }
    
    override suspend fun inputText(text: String): StepResult = withContext(Dispatchers.IO) {
        try {
            val bundle = Bundle()
            bundle.putString(AccessibilityService.EXTRA_INPUT_CONTENT_ITEM_RESPONSE, text)
            
            val result = accessibilityService.performGlobalAction(AccessibilityService.GLOBAL_ACTION_PASTE)
            
            // 等待文本输入
            delay(500)
            
            return@withContext if (result) {
                StepResult.success()
            } else {
                StepResult.failure("输入文本失败")
            }
        } catch (e: Exception) {
            return@withContext StepResult.failure("输入文本失败: ${e.message}")
        }
    }
    
    override suspend fun backPress(): StepResult = withContext(Dispatchers.IO) {
        try {
            val result = accessibilityService.performGlobalAction(AccessibilityService.GLOBAL_ACTION_BACK)
            
            return@withContext if (result) {
                StepResult.success()
            } else {
                StepResult.failure("返回操作失败")
            }
        } catch (e: Exception) {
            return@withContext StepResult.failure("返回操作失败: ${e.message}")
        }
    }
    
    override suspend fun homePress(): StepResult = withContext(Dispatchers.IO) {
        try {
            val result = accessibilityService.performGlobalAction(AccessibilityService.GLOBAL_ACTION_HOME)
            
            return@withContext if (result) {
                StepResult.success()
            } else {
                StepResult.failure("主页操作失败")
            }
        } catch (e: Exception) {
            return@withContext StepResult.failure("主页操作失败: ${e.message}")
        }
    }
    
    override suspend fun launchApp(packageName: String): StepResult = withContext(Dispatchers.IO) {
        try {
            val intent = context.packageManager.getLaunchIntentForPackage(packageName)
                ?: return@withContext StepResult.failure("无法获取应用启动Intent")
                
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
            context.startActivity(intent)
            
            // 等待应用启动
            delay(3000)
            
            return@withContext StepResult.success()
        } catch (e: Exception) {
            return@withContext StepResult.failure("启动应用失败: ${e.message}")
        }
    }
} 